using System;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Collections.Generic;
using ContactPrinter.Extension;
using ContactPrinter.Model.Interfaces;
using Google.Contacts;

namespace ContactPrinter.Model
{
    public class GoogleContact : IContact
    {
        private readonly Contact contact;

        public GoogleContact(Contact contact)
        {
            Contract.Requires<ArgumentNullException>(contact.PostalAddresses != null);
            Contract.Requires<ArgumentNullException>(contact.Organizations != null);
            Contract.Requires<ArgumentNullException>(contact.Emails != null);
            Contract.Requires<ArgumentNullException>(contact.Phonenumbers != null);

            this.contact = contact;
            Name = new GoogleName(contact.Name);
            PrimaryPostalAddress = new GooglePostalAddress(contact.PrimaryPostalAddress);
            PostalAddresses = contact.PostalAddresses.Select(address => new GooglePostalAddress(address)).Cast<IPostalAddress>().ToList();
            Organizations = contact.Organizations.Select(organization => new GoogleOrganization(organization)).Cast<IOrganization>().ToList();
            Emails = contact.Emails.Select(email => new Email(email.Address, CategorizedAttributeBase.FromRelString(email.Rel))).Cast<IEmail>().ToList();
            Phonenumbers = contact.Phonenumbers.Select(phoneNumber => new PhoneNumber(phoneNumber.Value, CategorizedAttributeBase.FromRelString(phoneNumber.Rel))).Cast<IPhoneNumber>().ToList();

            if (contact.PrimaryEmail != null)
            {
                PrimaryEmail = new Email(contact.PrimaryEmail.Address, CategorizedAttributeBase.FromRelString(contact.PrimaryEmail.Rel));
            }

            if (contact.PrimaryPhonenumber != null)
            {
                PrimaryPhonenumber = new PhoneNumber(contact.PrimaryPhonenumber.Value, CategorizedAttributeBase.FromRelString(contact.PrimaryPhonenumber.Rel));
            }
        }

        #region Implementation of IContact

        public string CategoryCapital
        {
            get
            {
                return DisplayedName.Substring(0, 1).ToUpper();
                //string captialLetter;
                //if (string.IsNullOrEmpty(Name.FullName))
                //{
                //    var organziation = this.GetPrimaryOrFirstOrganization();
                //    captialLetter = organziation != null ? organziation.Name.Substring(0, 1) : "#";
                //}
                //else
                //{
                //    captialLetter = Name.FullName.Substring(0, 1);
                //}
                //return captialLetter.ToUpper();
            }
        }

        public string DisplayedName
        {
            get 
            { 
                var displayedName = Name.DisplayedName;
                if (displayedName == null)
                {
                    var organization = this.GetPrimaryOrFirstOrganization();
                    displayedName = organization.Name;

                }
                return displayedName;
            }
        }

        public IName Name { get; set; }

        public IEmail PrimaryEmail { get; set; }

        public IPhoneNumber PrimaryPhonenumber { get; set; }

        public IPostalAddress PrimaryPostalAddress { get; private set; }

        public IList<IEmail> Emails { get; set; }

        public IList<IPhoneNumber> Phonenumbers { get; set; }

        public IList<IPostalAddress> PostalAddresses { get; private set; }

        public IList<IOrganization> Organizations { get; private set; }

        public string Location
        {
            get { return contact.Location; }
            set { throw new NotImplementedException(); }
        }

        public string Title
        {
            get { return contact.Title; }
            set { throw new NotImplementedException(); }
        }

        public string Author
        {
            get { return contact.Author; }
            set { throw new NotImplementedException(); }
        }

        public string Content
        {
            get { return contact.Content; }
            set { throw new NotImplementedException(); }
        }

        public string Summary
        {
            get { return contact.Summary; }
            set { throw new NotImplementedException(); }
        }

        public DateTime Updated
        {
            get { return contact.Updated; }
        }

        #endregion

        #region Implementation of IComparable

        public int CompareTo(object obj)
        {
            var otherContact = obj as IContact;
            if (otherContact == null)
                throw new ArgumentException("Object is not a IContact");

            ////order by company
            //var organization = this.GetPrimaryOrFirstOrganization();
            //if (organization != null)
            //{
            //    var otherOrganization = otherContact.GetPrimaryOrFirstOrganization();
            //    return organization.CompareTo(otherOrganization);
            //}

            //order by name
            return Name.CompareTo(otherContact.Name);
        }

        #endregion
    }
}